/**
 *	@file	scr_safari.c
 *	@brief	サファリ関連スクリプトコマンド群
 *	@author	Miyuki Iwasawa
 *	@date	08.10.28
 */

#include "common.h"
#include "fieldsys.h"

#include "system/snd_tool.h"
#include "system/wordset.h"
#include "poketool/poke_tool.h"

#include "script.h"
#include "scrcmd_def.h"
#include "field/field.h"
#include "field/eventflag.h"
#include "field/evwkdef.h"
#include "zonedata.h"
#include "sysflag.h"
#include "syswork.h"
#include "ev_mapchange.h"
#include "fld_bgm.h"
#include "scrcmd.h"
#include "ev_trainer.h"				//EvTrainer
#include "field_encount.h"			//DebugFieldEncount
#include "field_battle.h"			//BattleParam_IsWinResult
#include "field_subproc.h"
#include "map3d_object.h"
#include "fielddata/script/savework.h"	//LOCALWORK定義参照用
#include "fielddata/maptable/zone_id.h"
#include "application/safari_l.h"
#include "safari/safari_sys.h"
#include "fld_safari.h"
#include "ev_safari.h"
#include "scr_safari.h"

//--------------------------------------------------------------------------------------------
/**
 * サファリ地形配置ツール呼び出し
 *
 * @param	core		仮想マシン制御構造体へのポインタ
 *
 * @return	"1"
 */
//--------------------------------------------------------------------------------------------
BOOL EvCmdSafariMapLayout( VM_MACHINE * core )
{
	void** buf = GetEvScriptWorkMemberAdrs(core->fsys, ID_EVSCR_SUBPROC_WORK);

	*buf = FieldSafariLayout_SetProc( core->fsys );
    VM_SetWait( core, EvWaitSubProcAndFree );
    return 1;
}

//--------------------------------------------------------------------------------------------
/**
 * サファリオブジェ配置ツール呼び出し
 *
 * @param	core		仮想マシン制御構造体へのポインタ
 *
 * @return	"1"
 */
//--------------------------------------------------------------------------------------------
BOOL EvCmdSafariObjLayout( VM_MACHINE * core )
{
    FIELDSYS_WORK* fsys = core->fsys;
	u16* ret_wk = VMGetWork(core);

	EventCmd_SafariObjLayout( core->event_work,ret_wk);
    return 1;
}

//--------------------------------------------------------------------------------------------
/**
 * サファリオブジェ名を指定バッファに登録
 *
 * @param	core		仮想マシン制御構造体へのポインタ
 *
 * @return	"0"
 */
//--------------------------------------------------------------------------------------------
BOOL EvCmdSafariObjName(VM_MACHINE * core )
{
	FIELDSYS_WORK * fsys	= core->fsys;
	WORDSET** wordset		= GetEvScriptWorkMemberAdrs( fsys, ID_EVSCR_WORDSET );
	u8 idx					= VMGetU8(core);
	u16	obj_id				= VMGetWorkValue(core);

	WORDSET_RegisterSafariObjName( *wordset, idx, obj_id );
	return 0;
}

//--------------------------------------------------------------------------------------------
/**
 * @brief 話しかけ位置のオブジェを取得
 *
 * @param	core		仮想マシン制御構造体へのポインタ
 *
 * @return	"0"
 */
//--------------------------------------------------------------------------------------------
BOOL EvCmdSafariTalkObjGet(VM_MACHINE * core )
{
	FIELDSYS_WORK * fsys	= core->fsys;
	WORDSET** wordset		= GetEvScriptWorkMemberAdrs( fsys, ID_EVSCR_WORDSET );
	u16* obj_id				= VMGetWork(core);
	u16* obj_idx			= VMGetWork(core);

	*obj_id = FieldSafari_SearchTalkObj(fsys,obj_idx);
	return 0;
}

//--------------------------------------------------------------------------------------------
/**
 * @brief 指定OBJをフィールド上から削除する
 *
 * @param	core		仮想マシン制御構造体へのポインタ
 *
 * @return	"0"
 */
//--------------------------------------------------------------------------------------------
BOOL EvCmdSafariObjRemove(VM_MACHINE * core )
{
	int gx,gz,block_id,dir;
	M3DO_PTR obj_ptr;
	SAFARI_LAYOUT* layout;
	FIELDSYS_WORK * fsys	= core->fsys;
	WORDSET** wordset		= GetEvScriptWorkMemberAdrs( fsys, ID_EVSCR_WORDSET );
	u16 obj_idx				= VMGetWorkValue(core);

	//プレイヤーの話しかけ座標を取得
	dir = Player_DirGet(fsys->player);
	gx = Player_NowGPosXGet(fsys->player) + FieldOBJ_DirAddValueGX(dir);
	gz = Player_NowGPosZGet(fsys->player) + FieldOBJ_DirAddValueGZ(dir);

	block_id = ((gz-32)/32)*SAFARI_FIELD_X+(gx-32)/32;
	layout = SafariSv_GetLayoutPointer(SaveData_GetSafariSave(fsys->savedata),SAFARI_LAYOUT_MINE);	//編集できるのは自分のだけ

	{
		int local_index,i,j;
		M3DO_PTR	obj_ptr;
		M3DOL_PTR	obj_list;
		SAFARI_OBJ_PARAM prm;
		SAFARI_OBJ* obj;
		u16* attr;
		u8* ex_attr;

		local_index = GetNowLocalIndex(fsys->map_cont_dat);
		Get3DObjListFromLocalIdx(local_index, fsys->map_cont_dat,&obj_list);
		attr = (u16*)GetDivMapAttribute(fsys->map_cont_dat,local_index);
		ex_attr = (u8*)GetDivMapExAttribute(fsys->map_cont_dat,local_index);

		obj = &layout->block[block_id].obj[obj_idx];
		SafariData_GetObjectParam(&prm,obj->id,MyStatus_GetMySex(SaveData_GetMyStatus(fsys->savedata)));

		for(i = obj->z;i > (obj->z-prm.siz_z);i--){
			for(j = obj->x;j < (obj->x+prm.siz_x);j++){
				attr[i*32+j] = (u16)ex_attr[i*32+j];
			}
		}
#if 0
		obj_ptr = M3DO_GetMap3DObjData(obj_list, obj_idx);
		M3DO_SetVanish(obj_ptr, TRUE);
#else
		for(i = 0;i < MAP_READ_OBJ_3D_MAX/*layout->block[block_id].obj_ct*/;i++){
			VecFx32 tv;
			s16 gx,gz;
			obj_ptr = M3DO_GetMap3DObjData(obj_list, i);
			if(!M3DO_IsValid(obj_ptr)){
				continue;
			}
			tv = M3DO_GetGlobalVec(obj_ptr);
			gx = (FX_Whole(tv.x)+(256-8))/16;
			gz = (FX_Whole(tv.z)+(256-8))/16;
			IWASAWA_PRINT("obj_x = %d, obj_z = %d, tx %08x, tz %08x, gx = %d,gz = %d,\n",obj->x,obj->z,tv.x,tv.z,gx,gz);
			if(	gx < obj->x ||
				gz > obj->z ||
				gx >= (obj->x+prm.siz_x) ||
				gz <= (obj->z-prm.siz_z)){
				continue;
			}
			M3DO_SetVanish(obj_ptr, TRUE);
			break;
		}
#endif
	}
	SafariLayout_DelObj(layout,block_id,obj_idx);
	return 0;
}

//--------------------------------------------------------------------------------------------
/**
 * @brief 今居るブロックに新規OBJをおけるかどうかチェック
 *
 * @param	core		仮想マシン制御構造体へのポインタ
 *
 * @return	"0"
 */
//--------------------------------------------------------------------------------------------
BOOL EvCmdIsSafariObjPlace(VM_MACHINE * core )
{
	u16* ret_wk = VMGetWork(core);

	*ret_wk = FieldSafari_ObjPlaceCheck(core->fsys);
	return 0;
}

//--------------------------------------------------------------------------------------------
/**
 * @brief ミッション条件クリアチェック
 *
 * @param	core		仮想マシン制御構造体へのポインタ
 *
 * @return	"0"
 */
//--------------------------------------------------------------------------------------------
BOOL EvCmdSafariMissionClearCheck(VM_MACHINE * core )
{
	int i,max;
	u32	my_id;
	u16 place_id;
	const u16 mons[] = {MONSNO_ISITUBUTE,MONSNO_SANDO};
	FIELDSYS_WORK * fsys	= core->fsys;
	u8	mission_id			= VMGetU8(core);
	u16* ret_wk				= VMGetWork(core);
	POKEPARTY* party = SaveData_GetTemotiPokemon(fsys->savedata);

	max = PokeParty_GetPokeCount( party );
	my_id = MyStatus_GetID(SaveData_GetMyStatus(fsys->savedata));

	//サファリのplace_idを取得
	place_id = ZoneData_GetPlaceNameID(ZONE_ID_D47R0102);
	for(i = 0;i < max;i++){
		POKEMON_PARAM* pp = PokeParty_GetMemberPointer(party,i);

		//タマゴは除外
		if(PokeParaGet(pp,ID_PARA_tamago_flag,NULL)){
			continue;
		}
		//親ID一致チェック
		if(PokeParaGet(pp,ID_PARA_id_no,NULL) != my_id){
			continue;
		}
		//モンスターナンバー一致チェック
		if(PokeParaGet(pp,ID_PARA_monsno,NULL) != mons[mission_id]){
			continue;
		}
		//成体で捕まえたかチェック
		if(PokeParaGet(pp,ID_PARA_get_place,NULL) != 0){
			continue;
		}
		if(PokeParaGet(pp,ID_PARA_birth_place,NULL) != place_id){	//サファリで捕まえたポケモン？
			continue;
		}
		*ret_wk = TRUE;
		return 0;
	}
	*ret_wk = FALSE;
	return 0;
}

//--------------------------------------------------------------------------------------------
/**
 * @brief イベントキータイムを設定する
 *
 * @param	core		仮想マシン制御構造体へのポインタ
 *
 * @return	"0"
 */
//--------------------------------------------------------------------------------------------
BOOL EvCmdSafariEventKeyTimeSet(VM_MACHINE * core )
{
	FIELDSYS_WORK * fsys	= core->fsys;

	SafariSv_SetEventKeyTime(SaveData_GetSafariSave(fsys->savedata),
		SaveData_GetPlayTime(fsys->savedata));
	return 0;
}